package com.foodorder.service;

import com.foodorder.entity.Coupon;
import com.foodorder.entity.UserCoupon;
import com.foodorder.repository.CouponRepository;
import com.foodorder.repository.UserCouponRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 优惠券服务类
 */
@Service
@RequiredArgsConstructor
public class CouponService {
    
    private final CouponRepository couponRepository;
    private final UserCouponRepository userCouponRepository;
    
    /**
     * 根据ID查找优惠券
     */
    public Coupon findById(Long id) {
        return couponRepository.findById(id).orElse(null);
    }
    
    /**
     * 根据店铺ID查找优惠券
     */
    public List<Coupon> findByStoreId(Long storeId) {
        return couponRepository.findByStoreIdAndStatus(storeId, Coupon.CouponStatus.ACTIVE);
    }
    
    /**
     * 查找平台优惠券
     */
    public List<Coupon> findPlatformCoupons() {
        return couponRepository.findByStoreIdIsNullAndStatus(Coupon.CouponStatus.ACTIVE);
    }
    
    /**
     * 查找可抢的红包
     */
    public List<Coupon> findGrabbableCoupons(Long storeId) {
        return couponRepository.findGrabbableCoupons(Coupon.CouponStatus.ACTIVE);
    }
    
    /**
     * 查找用户可用的优惠券
     */
    public List<UserCoupon> findUserAvailableCoupons(Long userId) {
        return userCouponRepository.findUserAvailableCoupons(userId);
    }
    
    /**
     * 查找用户在指定店铺可用的优惠券
     */
    public List<UserCoupon> findUserAvailableCouponsForStore(Long userId, Long storeId) {
        return userCouponRepository.findUserAvailableCouponsForStore(userId, storeId);
    }
    
    /**
     * 抢红包/领取优惠券
     */
    @Transactional
    public boolean claimCoupon(Long userId, Long couponId) {
        Coupon coupon = findById(couponId);
        if (coupon == null) {
            return false;
        }
        
        // 检查优惠券是否可领取
        if (!isCouponClaimable(coupon, userId)) {
            return false;
        }
        
        // 创建用户优惠券关联
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.setUserId(userId);
        userCoupon.setCouponId(couponId);
        userCoupon.setStatus(UserCoupon.UseStatus.UNUSED);
        userCouponRepository.save(userCoupon);
        
        // 更新优惠券领取数量
        coupon.setClaimedCount(coupon.getClaimedCount() + 1);
        couponRepository.save(coupon);
        
        return true;
    }
    
    /**
     * 使用优惠券
     */
    @Transactional
    public boolean useCoupon(Long userId, Long couponId, Long orderId) {
        UserCoupon userCoupon = userCouponRepository.findByUserIdAndCouponId(userId, couponId)
                .orElse(null);
        
        if (userCoupon == null || userCoupon.getStatus() != UserCoupon.UseStatus.UNUSED) {
            return false;
        }
        
        // 更新使用状态
        userCoupon.setStatus(UserCoupon.UseStatus.USED);
        userCoupon.setUsedOrderId(orderId);
        userCoupon.setUsedAt(LocalDateTime.now());
        userCouponRepository.save(userCoupon);
        
        return true;
    }
    
    /**
     * 创建优惠券
     */
    public Coupon createCoupon(Coupon coupon) {
        return couponRepository.save(coupon);
    }
    
    /**
     * 检查优惠券是否可领取
     */
    private boolean isCouponClaimable(Coupon coupon, Long userId) {
        // 检查优惠券状态
        if (coupon.getStatus() != Coupon.CouponStatus.ACTIVE) {
            return false;
        }
        
        // 检查有效期
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(coupon.getValidFrom()) || now.isAfter(coupon.getValidTo())) {
            return false;
        }
        
        // 检查库存
        if (coupon.getClaimedCount() >= coupon.getTotalCount()) {
            return false;
        }
        
        // 检查用户领取限制
        long userClaimedCount = userCouponRepository.countByUserIdAndCouponId(userId, coupon.getId());
        if (userClaimedCount >= coupon.getLimitPerUser()) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 查找可用的优惠券（下单时使用）
     */
    public List<Coupon> findAvailableCoupons(Long storeId, BigDecimal orderAmount) {
        return couponRepository.findAvailableCoupons(Coupon.CouponStatus.ACTIVE);
    }
    
    /**
     * 保存优惠券
     */
    public Coupon save(Coupon coupon) {
        return couponRepository.save(coupon);
    }
    
    /**
     * 删除优惠券
     */
    public void deleteById(Long id) {
        couponRepository.deleteById(id);
    }
    
    /**
     * 查找即将过期的优惠券
     */
    public List<Coupon> findExpiringCoupons(LocalDateTime expireTime) {
        return couponRepository.findExpiringCoupons(LocalDateTime.now(), expireTime);
    }
    
    /**
     * 获取拥有指定优惠券的用户
     */
    public List<UserCoupon> getUserCouponsForCoupon(Long couponId) {
        return userCouponRepository.findByCouponId(couponId);
    }
    
    /**
     * 管理端分页查询优惠券
     */
    public Page<Coupon> findCouponsForAdmin(String keyword, String status, String type, Long storeId, Pageable pageable) {
        Specification<Coupon> spec = Specification.where(null);
        
        if (keyword != null && !keyword.trim().isEmpty()) {
            spec = spec.and((root, query, criteriaBuilder) -> 
                criteriaBuilder.or(
                    criteriaBuilder.like(root.get("name"), "%" + keyword + "%"),
                    criteriaBuilder.like(root.get("description"), "%" + keyword + "%")
                )
            );
        }
        
        if (status != null && !status.trim().isEmpty()) {
            try {
                Coupon.CouponStatus couponStatus = Coupon.CouponStatus.valueOf(status.toUpperCase());
                spec = spec.and((root, query, criteriaBuilder) -> 
                    criteriaBuilder.equal(root.get("status"), couponStatus)
                );
            } catch (IllegalArgumentException e) {
                // 忽略无效状态
            }
        }
        
        if (type != null && !type.trim().isEmpty()) {
            try {
                Coupon.CouponType couponType = Coupon.CouponType.valueOf(type.toUpperCase());
                spec = spec.and((root, query, criteriaBuilder) -> 
                    criteriaBuilder.equal(root.get("type"), couponType)
                );
            } catch (IllegalArgumentException e) {
                // 忽略无效类型
            }
        }
        
        if (storeId != null) {
            spec = spec.and((root, query, criteriaBuilder) -> 
                criteriaBuilder.equal(root.get("storeId"), storeId)
            );
        }
        
        return couponRepository.findAll(spec, pageable);
    }

    /**
     * 更新优惠券
     */
    public Coupon updateCoupon(Coupon coupon) {
        return couponRepository.save(coupon);
    }
    
    /**
     * 删除优惠券
     */
    @Transactional
    public void deleteCoupon(Long id) {
        // 先删除相关的用户优惠券
        userCouponRepository.deleteByCouponId(id);
        // 再删除优惠券
        couponRepository.deleteById(id);
    }
    
    /**
     * 批量删除优惠券
     */
    @Transactional
    public void deleteByIds(List<Long> ids) {
        for (Long id : ids) {
            deleteCoupon(id);
        }
    }
    
    /**
     * 更新优惠券状态
     */
    @Transactional
    public void updateStatus(Long id, String status) {
        Coupon coupon = couponRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("优惠券不存在"));
        
        try {
            Coupon.CouponStatus couponStatus = Coupon.CouponStatus.valueOf(status.toUpperCase());
            coupon.setStatus(couponStatus);
            couponRepository.save(coupon);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("无效的状态值: " + status);
        }
    }
    
    /**
     * 获取优惠券统计信息
     */
    public Map<String, Object> getCouponStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总优惠券数
        long totalCoupons = couponRepository.count();
        statistics.put("totalCoupons", totalCoupons);
        
        // 活跃优惠券数
        long activeCoupons = couponRepository.countByStatus(Coupon.CouponStatus.ACTIVE);
        statistics.put("activeCoupons", activeCoupons);
        
        // 已暂停优惠券数
        long pausedCoupons = couponRepository.countByStatus(Coupon.CouponStatus.PAUSED);
        statistics.put("pausedCoupons", pausedCoupons);
        
        // 已过期优惠券数
        long expiredCoupons = couponRepository.countByStatus(Coupon.CouponStatus.EXPIRED);
        statistics.put("expiredCoupons", expiredCoupons);
        
        // 总用户优惠券数
        long totalUserCoupons = userCouponRepository.count();
        statistics.put("totalUserCoupons", totalUserCoupons);
        
        // 已使用的用户优惠券数
        long usedUserCoupons = userCouponRepository.countByStatus(UserCoupon.UseStatus.USED);
        statistics.put("usedUserCoupons", usedUserCoupons);
        
        return statistics;
    }
}